﻿


using IotClientService.Extensions;
using IotClientService.Handles;
using IotClientService.Handles.hks;
using IotContract.Dtos.Clients.Equips;
using IotContract.Dtos.Servers;
using IotContract.Events;
using IotContract.Interfaces;
using IotContract.Models.Clients;
using IotContract.Models.Clients.Hks;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using XT.Common.Extensions;

namespace IotClientService.Operations.hk;
/// <summary>
/// 杭可筛选机操作
/// </summary>
public class HkSelOperation : IEquipOperation<HkSelEquipDto>
{
    public event EventHandler<ConnectStatusEventArgs> OnConnectStatusChanged;
   

    
    private CancellationTokenSource _cancellationTokenSource;

    private Task _operationTask;

    private HkSelEquipDto _group;

    private HkSelTcpHandle _tcpHandle;

    private int _errorCode = 0;


    private string log;







    private int sgPLCAddr;
    private int sgIMSAddr;
   

    private DateTime buffSave;
    private string sAlarmStr;
   

    private System.Timers.Timer _timer;

    private bool _status = false;

    private int _errorCount = 0;

    private IConnectDataService _connectDataService;

    public ParserDefine _parser = new ParserDefine();


    public HkSelOperation(IConnectDataService connectDataService)
    {
        _connectDataService = connectDataService;
        _tcpHandle = new HkSelTcpHandle();
        _tcpHandle.OnConnectLogChanged += _tcpHandle_OnConnectLogChanged; ;
    }

    private void _tcpHandle_OnConnectLogChanged(object? sender, ConnectStatusEventArgs e)
    {
        OnConnectStatusChanged?.Invoke(this, e);
    }

    public bool GetConnection()
    {
        return _tcpHandle.GetConnection();
    }

    public HkSelEquipDto GetEquipInfo()
    {
        return _group;
    }

    public bool GetOperationStatus()
    {
        return _status;
    }

    public async Task<bool> Init(HkSelEquipDto group, IEnumerable<EquipTagDto> tags = null)
    {
        _group = group;
        _tcpHandle.Init(_connectDataService, _group);
        return true;
    }

    public async Task<bool> OperationStart()
    {
        if (_operationTask != null && GetConnection())
        {
           await OperationStop();

        }
        _cancellationTokenSource = new CancellationTokenSource();
        //_operationTask = Task.Factory.StartNew(() => ThreadScheduler(), _token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
        _timer = new System.Timers.Timer();
        _timer.AutoReset = true;
        _timer.Interval = 1000;

        _timer.Elapsed += _timer_Elapsed;
        _timer.Start();
        _status = true;

        return true;
    }

    private async void _timer_Elapsed(object? sender, ElapsedEventArgs e)
    {

        try
        {
            if ( _cancellationTokenSource.IsCancellationRequested)
            {
                return;
            }

            if (_errorCount > 50)
            {
               await OperationStop();
            }

            await _tcpHandle.RecieveData();
            CommControl();

        }
        catch (Exception exception)
        {
            OnConnectStatusChanged?.Invoke(this, new ConnectStatusEventArgs
            {
                Message = exception.Message,
                Connect = false,
                IsSuccess = true

            });
        }
    }

    #region CommControl

    public static byte Lo(int v)
    {
        string str = Convert.ToString(v, 16);
        str = str.PadLeft(4, '0');
        string str1 = str.Substring(2, 2);
        return Convert.ToByte(Convert.ToInt32(str1, 16));
    }

    public static byte Hi(int v)
    {
        string str = Convert.ToString(v, 16);
        str = str.PadLeft(4, '0');
        string str1 = str.Substring(0, 2);
        return Convert.ToByte(Convert.ToInt32(str1, 16));
    }
    private void Lf_WriteCharactorPLC(int address, string sval, int length)
    {
        int num = 0;
        char paddingChar = Convert.ToChar(0);
        string text = "";
        if (length % 2 > 0)
        {
            text = sval.PadRight(length + 1, paddingChar);
            num = (length + 1) / 2;
        }
        else
        {
            text = sval.PadRight(length, paddingChar);
            num = length / 2;
        }
        for (int i = 0; i < num; i++)
        {
            _tcpHandle.CnvC.DbuffW[address + i] = Convert.ToByte(text[i * 2]) + Convert.ToByte(text[i * 2 + 1]) * 256;
        }
    }

    public static string Lf_Copy(string str, int start, int cutsize)
    {
        string text = "";
        int num = start - 1;
        text = str.Substring(num, str.Length - num);
        if (cutsize >= text.Length)
        {
            return text;
        }
        return text.Substring(0, cutsize);
    }

    public static int Lf_StrToIntDef(string s, int @default)
    {
        if (int.TryParse(s, out var result))
        {
            return result;
        }
        return @default;
    }

    private void CommPhase00()
    {
        if (!this.GetConnection())
        {
            _tcpHandle.DisconnectServer();
            this._tcpHandle.ConnectServer(_group);
            this._tcpHandle.CnvC.CommSts = 99;
        }

    }
   
    private void CommPhase10()
    {
        var CnvC = this._tcpHandle.CnvC;

        // 写入请求标志
        if (CnvC.DwReq == 0)
        {
            CnvC.CommPhs = 20;
            return;
        }
        if (CnvC.DwStart < CnvC.DwWordS)
        {
            CnvC.DwStart = CnvC.DwWordS;
        }
        if (CnvC.DwStart > CnvC.DwWordE)
        {
            CnvC.DwStart = CnvC.DwWordS;
        }
        CnvC.DwLen = CnvC.DwWordE - CnvC.DwStart + 1;
        if (CnvC.DwLen > 500)
        {
            CnvC.DwLen = 500;
        }
        CnvC.TxBuffB[0] = 80;
        CnvC.TxBuffB[1] = 0;
        CnvC.TxBuffB[2] = 0;
        CnvC.TxBuffB[3] = byte.MaxValue;
        CnvC.TxBuffB[4] = byte.MaxValue;
        CnvC.TxBuffB[5] = 3;
        CnvC.TxBuffB[6] = 0;
        CnvC.TxBuffB[7] = Lo(12 + CnvC.DwLen * 2);
        CnvC.TxBuffB[8] = Hi(12 + CnvC.DwLen * 2);
        CnvC.TxBuffB[9] = 16;
        CnvC.TxBuffB[10] = 0;
        CnvC.TxBuffB[11] = 1;
        CnvC.TxBuffB[12] = 20;
        CnvC.TxBuffB[13] = 0;
        CnvC.TxBuffB[14] = 0;
        CnvC.TxBuffB[15] = Lo(CnvC.DwStart + CnvC.DwAddr);
        CnvC.TxBuffB[16] = Hi(CnvC.DwStart + CnvC.DwAddr);
        CnvC.TxBuffB[17] = 0;
        CnvC.TxBuffB[18] = _tcpHandle.DEVICE_CODE;
        CnvC.TxBuffB[19] = Lo(CnvC.DwLen);
        CnvC.TxBuffB[20] = Hi(CnvC.DwLen);
        for (int i = 0; i < CnvC.DwLen; i++)
        {
            CnvC.TxBuffB[i * 2 + 21] = Lo(CnvC.DbuffW[CnvC.DwStart + i]);
            CnvC.TxBuffB[i * 2 + 22] = Hi(CnvC.DbuffW[CnvC.DwStart + i]);
        }
        SendData(CnvC.DwLen * 2 + 21);
        CnvC.CommPhs = 11;



    }

    private void SendData(int txcnt)
    {
        this._tcpHandle.CnvC.RxEnd = 0;


        // 先注释发送
        this._tcpHandle.PlcWrite(this._tcpHandle.CnvC.TxBuffB, txcnt);

    }

    private void CommPhase11()
    {
        if (_tcpHandle.CnvC.RxBuffB[0] != 208)
        {

            _tcpHandle.CnvC.CommPhs = 10;
        }
        else if (_tcpHandle.CnvC.RxBuffB[9] != 0)
        {

            _tcpHandle.CnvC.CommPhs = 10;
        }
        else if (_tcpHandle.CnvC.RxBuffB[10] == 0)
        {

            _tcpHandle.CnvC.CommPhs = 10;
            _tcpHandle.CnvC.DwStart = _tcpHandle.CnvC.DwStart + _tcpHandle.CnvC.DwLen;
            if (_tcpHandle.CnvC.DwStart > _tcpHandle.CnvC.DwWordE)
            {
                _tcpHandle.CnvC.DwReq = 0;
                _tcpHandle.CnvC.DwAddr = 0;
                _tcpHandle.CnvC.CommPhs = 20;
            }

        }
        else
        {

            _tcpHandle.CnvC.CommPhs = 10;
        }
    }

    private void CommPhase20()
    {
        var PLC = _tcpHandle;
        if (PLC.CnvC.DwReq > 0)
        {
            PLC.CnvC.CommPhs = 30;
            return;
        }
        if (PLC.CnvC.DwRet == 0)
        {
            PLC.CnvC.CommPhs = 30;
            return;
        }
        PLC.CnvC.DwLen = 1;
        PLC.CnvC.TxBuffB[0] = 80;
        PLC.CnvC.TxBuffB[1] = 0;
        PLC.CnvC.TxBuffB[2] = 0;
        PLC.CnvC.TxBuffB[3] = byte.MaxValue;
        PLC.CnvC.TxBuffB[4] = byte.MaxValue;
        PLC.CnvC.TxBuffB[5] = 3;
        PLC.CnvC.TxBuffB[6] = 0;
        PLC.CnvC.TxBuffB[7] = Lo(12 + PLC.CnvC.DwLen * 2);
        PLC.CnvC.TxBuffB[8] = Hi(12 + PLC.CnvC.DwLen * 2);
        PLC.CnvC.TxBuffB[9] = 16;
        PLC.CnvC.TxBuffB[10] = 0;
        PLC.CnvC.TxBuffB[11] = 1;
        PLC.CnvC.TxBuffB[12] = 20;
        PLC.CnvC.TxBuffB[13] = 0;
        PLC.CnvC.TxBuffB[14] = 0;
        PLC.CnvC.TxBuffB[15] = Lo(PLC.CnvC.DwRetAddr);
        PLC.CnvC.TxBuffB[16] = Hi(PLC.CnvC.DwRetAddr);
        PLC.CnvC.TxBuffB[17] = 0;
        PLC.CnvC.TxBuffB[18] = PLC.DEVICE_CODE;
        PLC.CnvC.TxBuffB[19] = Lo(PLC.CnvC.DwLen);
        PLC.CnvC.TxBuffB[20] = Hi(PLC.CnvC.DwLen);
        for (int i = 0; i < PLC.CnvC.DwLen; i++)
        {
            PLC.CnvC.TxBuffB[i * 2 + 21] = Lo(PLC.CnvC.DbuffW[PLC.CnvC.DwRet + i]);
            PLC.CnvC.TxBuffB[i * 2 + 22] = Hi(PLC.CnvC.DbuffW[PLC.CnvC.DwRet + i]);
        }
        SendData(PLC.CnvC.DwLen * 2 + 21);
        PLC.CnvC.CommPhs = 21;
    }

    private void CommPhase21()
    {
        if (_tcpHandle.CnvC.RxBuffB[0] != 208)
        {

            _tcpHandle.CnvC.CommPhs = 20;
        }
        else if (_tcpHandle.CnvC.RxBuffB[9] != 0)
        {

            _tcpHandle.CnvC.CommPhs = 20;
        }
        else if (_tcpHandle.CnvC.RxBuffB[10] == 0)
        {

            _tcpHandle.CnvC.DwRet = 0;
            _tcpHandle.CnvC.DwRetAddr = 0;
            _tcpHandle.CnvC.CommPhs = 30;
        }
        else
        {

            _tcpHandle.CnvC.CommPhs = 20;
        }
    }

    private void CommPhase30()
    {
        var PLC = _tcpHandle;
        if (PLC.CnvC.DwReq > 0)
        {
            PLC.CnvC.CommPhs = 40;
            return;
        }
        if (PLC.CnvC.DwInfoAdd1 == 0)
        {
            PLC.CnvC.CommPhs = 40;
            return;
        }
        if (PLC.CnvC.DwStart < PLC.CnvC.DwWordS)
        {
            PLC.CnvC.DwStart = PLC.CnvC.DwWordS;
        }
        if (PLC.CnvC.DwStart > PLC.CnvC.DwWordE)
        {
            PLC.CnvC.DwStart = PLC.CnvC.DwWordS;
        }
        PLC.CnvC.DwLen = PLC.CnvC.DwWordE - PLC.CnvC.DwStart + 1;
        if (PLC.CnvC.DwLen > 500)
        {
            PLC.CnvC.DwLen = 500;
        }
        PLC.CnvC.TxBuffB[0] = 80;
        PLC.CnvC.TxBuffB[1] = 0;
        PLC.CnvC.TxBuffB[2] = 0;
        PLC.CnvC.TxBuffB[3] = byte.MaxValue;
        PLC.CnvC.TxBuffB[4] = byte.MaxValue;
        PLC.CnvC.TxBuffB[5] = 3;
        PLC.CnvC.TxBuffB[6] = 0;
        PLC.CnvC.TxBuffB[7] = Lo(12 + PLC.CnvC.DwLen * 2);
        PLC.CnvC.TxBuffB[8] = Hi(12 + PLC.CnvC.DwLen * 2);
        PLC.CnvC.TxBuffB[9] = 16;
        PLC.CnvC.TxBuffB[10] = 0;
        PLC.CnvC.TxBuffB[11] = 1;
        PLC.CnvC.TxBuffB[12] = 20;
        PLC.CnvC.TxBuffB[13] = 0;
        PLC.CnvC.TxBuffB[14] = 0;
        PLC.CnvC.TxBuffB[15] = Lo(PLC.CnvC.DwInfoAdd1 + PLC.DBUFF_OFFSET);
        PLC.CnvC.TxBuffB[16] = Hi(PLC.CnvC.DwInfoAdd1 + PLC.DBUFF_OFFSET);
        PLC.CnvC.TxBuffB[17] = 0;
        PLC.CnvC.TxBuffB[18] = PLC.DEVICE_CODE;
        PLC.CnvC.TxBuffB[19] = Lo(PLC.CnvC.DwLen);
        PLC.CnvC.TxBuffB[20] = Hi(PLC.CnvC.DwLen);
        for (int i = 0; i < PLC.CnvC.DwLen; i++)
        {
            PLC.CnvC.TxBuffB[i * 2 + 21] = Lo(PLC.CnvC.DbuffW[PLC.CnvC.DwInfoAdd1 + i]);
            PLC.CnvC.TxBuffB[i * 2 + 22] = Hi(PLC.CnvC.DbuffW[PLC.CnvC.DwInfoAdd1 + i]);
        }
        SendData(PLC.CnvC.DwLen * 2 + 21);
        PLC.CnvC.CommPhs = 31;
    }

    private void CommPhase31()
    {
        if (_tcpHandle.CnvC.RxBuffB[0] != 208)
        {

            _tcpHandle.CnvC.CommPhs = 30;
        }
        else if (_tcpHandle.CnvC.RxBuffB[9] != 0)
        {

            _tcpHandle.CnvC.CommPhs = 30;
        }
        else if (_tcpHandle.CnvC.RxBuffB[10] == 0)
        {

            _tcpHandle.CnvC.DwInfoAdd1 = 0;
            _tcpHandle.CnvC.CommPhs = 40;

        }
        else
        {

            _tcpHandle.CnvC.CommPhs = 30;
        }
    }
    private void PlcCommErr(int code)
    {
        var PLC = _tcpHandle;
        PLC.CnvC.CommSts = 1;
        _errorCode = code;
        if (code == 9)
        {
            _errorCode = PLC.CnvC.RxBuffB[9];
        }
        _group.Value = "Sel Communication Error (" + _errorCode + ")";
    }

    private void PlcCommGood()
    {

        _errorCode = 0;
        _group.Value = "";
    }
    private void CommPhase40()
    {
        if (_tcpHandle.CnvC.DrStart < _tcpHandle.DR_WordS)
        {
            _tcpHandle.CnvC.DrStart = _tcpHandle.DR_WordS;
        }
        if (_tcpHandle.CnvC.DrStart > _tcpHandle.DR_WordE)
        {
            _tcpHandle.CnvC.DrStart = _tcpHandle.DR_WordS;
        }
        _tcpHandle.CnvC.DrLen = _tcpHandle.DR_WordE - _tcpHandle.CnvC.DrStart + 1;
        if (_tcpHandle.CnvC.DrLen > 500)
        {
            _tcpHandle.CnvC.DrLen = 500;
        }
        _tcpHandle.CnvC.TxBuffB[0] = 80;
        _tcpHandle.CnvC.TxBuffB[1] = 0;
        _tcpHandle.CnvC.TxBuffB[2] = 0;
        _tcpHandle.CnvC.TxBuffB[3] = 255;
        _tcpHandle.CnvC.TxBuffB[4] = 255;
        _tcpHandle.CnvC.TxBuffB[5] = 3;
        _tcpHandle.CnvC.TxBuffB[6] = 0;
        _tcpHandle.CnvC.TxBuffB[7] = 12;
        _tcpHandle.CnvC.TxBuffB[8] = 0;
        _tcpHandle.CnvC.TxBuffB[9] = 0;
        _tcpHandle.CnvC.TxBuffB[10] = 0;
        _tcpHandle.CnvC.TxBuffB[11] = 1;
        _tcpHandle.CnvC.TxBuffB[12] = 4;
        _tcpHandle.CnvC.TxBuffB[13] = 0;
        _tcpHandle.CnvC.TxBuffB[14] = 0;
        _tcpHandle.CnvC.TxBuffB[15] = Lo(_tcpHandle.CnvC.DrStart + _tcpHandle.DBUFF_OFFSET);
        _tcpHandle.CnvC.TxBuffB[16] = Hi(_tcpHandle.CnvC.DrStart + _tcpHandle.DBUFF_OFFSET);
        _tcpHandle.CnvC.TxBuffB[17] = 0;
        _tcpHandle.CnvC.TxBuffB[18] = _tcpHandle.DEVICE_CODE;
        _tcpHandle.CnvC.TxBuffB[19] = Lo(_tcpHandle.CnvC.DrLen);
        _tcpHandle.CnvC.TxBuffB[20] = Hi(_tcpHandle.CnvC.DrLen);
        this.SendData(21);
        _tcpHandle.CnvC.CommPhs = 41;
    }



    private void CommPhase41()
    {
        var PLC = _tcpHandle;
        if (PLC.CnvC.TimeOut > 0)
        {
            PlcCommErr(1);
            PLC.CnvC.CommPhs = 40;
            return;
        }
        if (PLC.CnvC.RxBuffB[0] != 208)
        {
            PlcCommErr(2);
            PLC.CnvC.CommPhs = 40;
            return;
        }
        if (PLC.CnvC.RxBuffB[9] != 0)
        {
            PlcCommErr(9);
            PLC.CnvC.CommPhs = 40;
            return;
        }
        if (PLC.CnvC.RxBuffB[10] != 0)
        {
            PlcCommErr(9);
            PLC.CnvC.CommPhs = 40;
            return;
        }
        PlcCommGood();
        for (int i = 0; i < PLC.CnvC.DrLen && PLC.CnvC.DrStart + i + 1 <= PLC.CnvC.DbuffR.Length && i * 2 + 12 <= PLC.CnvC.RxCnt; i++)
        {
            PLC.CnvC.DbuffR[PLC.CnvC.DrStart + i] = (PLC.CnvC.RxBuffB[i * 2 + 11] + PLC.CnvC.RxBuffB[i * 2 + 12] * 256) & 0xFFFF;
        }
        PLC.CnvC.CommPhs = 50;
        PLC.CnvC.DrStart = PLC.CnvC.DrStart + PLC.CnvC.DrLen;
        if (PLC.CnvC.DrStart < PLC.DR_WordE)
        {
            PLC.CnvC.CommPhs = 40;
        }

    }
    /// <summary>
    /// 心跳
    /// </summary>
    private void CommPhase50()
    {
        _tcpHandle.CnvC.DwLen = _tcpHandle.DW_WordE - _tcpHandle.DW_WordS + 1;
        if (_tcpHandle.CnvC.DwLen > 500)
        {
            _tcpHandle.CnvC.DwLen = 500;
        }
        _tcpHandle.CnvC.TxBuffB[0] = 80;
        _tcpHandle.CnvC.TxBuffB[1] = 0;
        _tcpHandle.CnvC.TxBuffB[2] = 0;
        _tcpHandle.CnvC.TxBuffB[3] = 255;
        _tcpHandle.CnvC.TxBuffB[4] = 255;
        _tcpHandle.CnvC.TxBuffB[5] = 3;
        _tcpHandle.CnvC.TxBuffB[6] = 0;
        _tcpHandle.CnvC.TxBuffB[7] = Lo(12 + _tcpHandle.CnvC.DwLen * 2);
        _tcpHandle.CnvC.TxBuffB[8] = Hi(12 + _tcpHandle.CnvC.DwLen * 2);
        _tcpHandle.CnvC.TxBuffB[9] = 16;
        _tcpHandle.CnvC.TxBuffB[10] = 0;
        _tcpHandle.CnvC.TxBuffB[11] = 1;
        _tcpHandle.CnvC.TxBuffB[12] = 20;
        _tcpHandle.CnvC.TxBuffB[13] = 0;
        _tcpHandle.CnvC.TxBuffB[14] = 0;
        _tcpHandle.CnvC.TxBuffB[15] = Lo(_tcpHandle.DW_WordS + _tcpHandle.DBUFF_OFFSET);
        _tcpHandle.CnvC.TxBuffB[16] = Hi(_tcpHandle.DW_WordS + _tcpHandle.DBUFF_OFFSET);
        _tcpHandle.CnvC.TxBuffB[17] = 0;
        _tcpHandle.CnvC.TxBuffB[18] = _tcpHandle.DEVICE_CODE;
        _tcpHandle.CnvC.TxBuffB[19] = Lo(_tcpHandle.CnvC.DwLen);
        _tcpHandle.CnvC.TxBuffB[20] = Hi(_tcpHandle.CnvC.DwLen);
        for (int i = 0; i < _tcpHandle.CnvC.DwLen; i++)
        {
            _tcpHandle.CnvC.TxBuffB[i * 2 + 21] = Lo(_tcpHandle.CnvC.DbuffW[_tcpHandle.DW_WordS + i]);
            _tcpHandle.CnvC.TxBuffB[i * 2 + 22] = Hi(_tcpHandle.CnvC.DbuffW[_tcpHandle.DW_WordS + i]);
        }
        this.SendData(_tcpHandle.CnvC.DwLen * 2 + 21);
        _tcpHandle.CnvC.CommPhs = 51;
    }


    private void HeartPLC()
    {
        _tcpHandle.CnvC.DwLen = _tcpHandle.DW_WordE - _tcpHandle.DW_WordS + 1;
        if (_tcpHandle.CnvC.DwLen > 500)
        {
            _tcpHandle.CnvC.DwLen = 500;
        }
        _tcpHandle.CnvC.TxBuffB[0] = 80;
        _tcpHandle.CnvC.TxBuffB[1] = 0;
        _tcpHandle.CnvC.TxBuffB[2] = 0;
        _tcpHandle.CnvC.TxBuffB[3] = 255;
        _tcpHandle.CnvC.TxBuffB[4] = 255;
        _tcpHandle.CnvC.TxBuffB[5] = 3;
        _tcpHandle.CnvC.TxBuffB[6] = 0;
        _tcpHandle.CnvC.TxBuffB[7] = Lo(12 + _tcpHandle.CnvC.DwLen * 2);
        _tcpHandle.CnvC.TxBuffB[8] = Hi(12 + _tcpHandle.CnvC.DwLen * 2);
        _tcpHandle.CnvC.TxBuffB[9] = 16;
        _tcpHandle.CnvC.TxBuffB[10] = 0;
        _tcpHandle.CnvC.TxBuffB[11] = 1;
        _tcpHandle.CnvC.TxBuffB[12] = 20;
        _tcpHandle.CnvC.TxBuffB[13] = 0;
        _tcpHandle.CnvC.TxBuffB[14] = 0;
        _tcpHandle.CnvC.TxBuffB[15] = Lo(_tcpHandle.DW_WordS + _tcpHandle.DBUFF_OFFSET);
        _tcpHandle.CnvC.TxBuffB[16] = Hi(_tcpHandle.DW_WordS + _tcpHandle.DBUFF_OFFSET);
        _tcpHandle.CnvC.TxBuffB[17] = 0;
        _tcpHandle.CnvC.TxBuffB[18] = _tcpHandle.DEVICE_CODE;
        _tcpHandle.CnvC.TxBuffB[19] = Lo(_tcpHandle.CnvC.DwLen);
        _tcpHandle.CnvC.TxBuffB[20] = Hi(_tcpHandle.CnvC.DwLen);
        for (int i = 0; i < _tcpHandle.CnvC.DwLen; i++)
        {
            _tcpHandle.CnvC.TxBuffB[i * 2 + 21] = Lo(_tcpHandle.CnvC.DbuffW[_tcpHandle.DW_WordS + i]);
            _tcpHandle.CnvC.TxBuffB[i * 2 + 22] = Hi(_tcpHandle.CnvC.DbuffW[_tcpHandle.DW_WordS + i]);
        }
        this.SendData(_tcpHandle.CnvC.DwLen * 2 + 21);

    }

    private void CommPhase51()
    {
        if (_tcpHandle.CnvC.RxBuffB[0] != 208)
        {
            PlcCommErr(2);

            _tcpHandle.CnvC.CommPhs = 50;
        }
        else if (_tcpHandle.CnvC.RxBuffB[9] != 0)
        {
            PlcCommErr(9);
            _tcpHandle.CnvC.CommPhs = 50;
        }
        else if (_tcpHandle.CnvC.RxBuffB[10] == 0)
        {
            PlcCommGood();
            _tcpHandle.CnvC.CommPhs = 90;


        }
        else
        {
            PlcCommErr(9);
            _tcpHandle.CnvC.CommPhs = 50;
        }
    }



    private void CommPhase90()
    {

        TrayInfomationSEL();

    }

    private void CommPhase91()
    {

        TrayResultdataSEL();

    }

    private void CommPhase92()
    {
        EquipmentState();
    }

    private void CommPhase93()
    {
        EquipmentAlarm();
    }


    #endregion

    #region 数据库

    #region Information
    /// <summary>
    /// 读取PLC
    /// </summary>
    /// <param name="address"></param>
    /// <param name="length"></param>
    /// <returns></returns>
    private string Lf_ReadCharactorPLC(int address, int length)
    {
        var PLC = _tcpHandle;
        string text = "";
        for (int i = 0; i < length; i++)
        {
            if (PLC.CnvC.DbuffR[address + i] != 0)
            {
                if (Lo(PLC.CnvC.DbuffR[address + i]) != 0)
                {
                    text += Convert.ToChar(Lo(PLC.CnvC.DbuffR[address + i]));
                }
                if (Hi(PLC.CnvC.DbuffR[address + i]) != 0)
                {
                    text += Convert.ToChar(Hi(PLC.CnvC.DbuffR[address + i]));
                }
            }
        }
        return text.Trim();
    }
    private bool DbuffRLow(int plcAddr, int imsAddr, ref string errorCode)
    {
        var PLC = _tcpHandle;
        if (PLC.CnvC.DbuffR[plcAddr] == 0)
        {
            if (PLC.CnvC.DbuffR[imsAddr] > 0)
            {
                PLC.CnvC.DbuffW[imsAddr] = 0;
                PLC.CnvC.DwRet = imsAddr;
                PLC.CnvC.DwRetAddr = PLC.DBUFF_OFFSET + imsAddr;
                PLC.CnvC.DwReq = 1;
                PLC.CnvC.DwAddr = PLC.DBUFF_OFFSET;
            }
        }
        else if (PLC.CnvC.DwReq <= 0 && PLC.CnvC.DwAddr <= 0 && PLC.CnvC.DwRetAddr <= 0)
        {

            ParserDefine trayInfo = new ParserDefine();
            string trayID = "";
            log = string.Empty;
            errorCode = string.Empty;
            int num = 0;
            int num3 = 0;
            try
            {

                trayID = Lf_ReadCharactorPLC(10, 4).Trim();


                trayInfo.TrayID = trayID;

                _group.TrayNo = trayID;

                log += string.Format("[{0}] {1} ({2})", DateTime.Now.ToString("HH:mm:ss"), "Tray Sortation", trayInfo.TrayID);


                trayInfo.StageNo = Lf_Copy(_group.Name, 7, 2).PadLeft(4, '0');

                // 判断TrayID  在  tb_ray 中是否存在
                num = 1;


                // 1 空  2 工程  
                num3 = 2;
                var result = _connectDataService.CheckNGResult(new HkWriteInstruct
                {
                    TrayID = trayID,
                    Num = _group.Num

                }).Result;
                if (result.IsSuccess)
                {
                    if (result.Msg == "999")
                    {
                        num3 = 1;

                    }
                }
                else
                {
                    errorCode = result.Msg;
                    _group.Value = $"{_group.ToString()} {trayID} 检查NG托盘类型失败， ErrorCode {result.Msg}";
                    OnConnectStatusChanged?.Invoke(this, new ConnectStatusEventArgs
                    {
                        IsSuccess = false,
                        Connect = GetConnection(),
                        Message = $"{_group.ToString()} {trayID} 检查NG托盘类型失败， ErrorCode {result.Msg}"
                    });
                }

                switch (num)
                {
                    case -1:
                        errorCode = "8215";
                        log = $"IMS-{errorCode} - Empty Tray or NG Tray.({trayInfo.TrayID})";
                        break;
                    case 0:
                        num3 = 1;
                        break;
                }
                if (num3 == 2)
                {
                    trayInfo.ProcType = "SEL";
                }


                GenerateData(trayInfo, errorCode, 20, 30);
                PLC.CnvC.DbuffW[21] = num3;
                var text7 = DateTime.Now.ToString("yyyyMMddHHmmss");
                PLC.CnvC.DbuffW[22] = Lf_StrToIntDef(Lf_Copy(text7, 1, 4), 0);
                PLC.CnvC.DbuffW[23] = Lf_StrToIntDef(Lf_Copy(text7, 5, 2), 0);
                PLC.CnvC.DbuffW[24] = Lf_StrToIntDef(Lf_Copy(text7, 7, 2), 0);
                PLC.CnvC.DbuffW[25] = Lf_StrToIntDef(Lf_Copy(text7, 9, 2), 0);
                PLC.CnvC.DbuffW[26] = Lf_StrToIntDef(Lf_Copy(text7, 11, 2), 0);
                PLC.CnvC.DbuffW[27] = Lf_StrToIntDef(Lf_Copy(text7, 13, 2), 0);
                log += string.Format("End Time [{0, -8}]:Type No({1, 4}), Proc No({2, 2}), Sortation({3, 1})", DateTime.Now.ToString("HH:mm:ss"), trayInfo.TypeNo, trayInfo.ProcNo, num3);
                log += "\n";
                return true;
            }
            catch (Exception ex)
            {
                log = $"ReceiveMessage1107 Error => {ex.Message}";
            }

        }

        return false;
    }


    private string DbuffRLow1(int plcAddr, int imsAddr)
    {
        string errorCode = string.Empty;
        var PLC = _tcpHandle;

        if (PLC.CnvC.DbuffR[plcAddr] == 0)
        {
            if (PLC.CnvC.DbuffR[imsAddr] > 0)
            {
                PLC.CnvC.DbuffW[imsAddr] = 0;
                PLC.CnvC.DwRet = sgIMSAddr;
                PLC.CnvC.DwRetAddr = PLC.DBUFF_OFFSET + imsAddr;
                PLC.CnvC.DwReq = 1;
                PLC.CnvC.DwAddr = PLC.DBUFF_OFFSET;
            }
        }
        else if (PLC.CnvC.DwReq <= 0 && PLC.CnvC.DwAddr <= 0 && PLC.CnvC.DwRetAddr <= 0)
        {
            // 请求接口
            ParserDefine trayInfo = new ParserDefine();
            log = string.Empty;

            string trayID = string.Empty;
            int num = 0;
            int num2 = 0;
            try
            {
                //for (int j = 0; j < 400; j++)
                //{
                //    trayInfo.Step[0].Slot[j].NgCell = 2;
                //    trayInfo.Step[0].Slot[j].CellId = "";
                //    trayInfo.Step[0].Slot[j].NgCode = "00";
                //}
                trayID = Lf_ReadCharactorPLC(40, 4).Trim();
                trayInfo.TrayID = trayID;


                log += string.Format("[{0}] {1} ({2})", DateTime.Now.ToString("HH:mm:ss"), "Process Tray Information", trayInfo.TrayID);
                trayInfo.StageNo = Lf_Copy(_group.Name, 7, 2).PadLeft(4, '0');
               
                // 获取结果
                var result = _connectDataService.GetSelCellData(new HkWriteInstruct
                {
                    TrayID = trayID,
                    Num = _group.Num

                }).Result;
                if (!result.IsSuccess)
                {

                    OnConnectStatusChanged?.Invoke(this, new ConnectStatusEventArgs
                    {
                        IsSuccess = false,
                        Connect = GetConnection(),
                        Message = $"{_group.ToString()} {trayID} 获取筛选结果失败 ErrorCode {result.Msg}"
                    });
                    _group.Value = $"{_group.ToString()} {trayID} 获取筛选结果失败 ErrorCode {result.Msg}";
                    errorCode = result.Msg;

                }
                else
                {
                    _group.Value = $"{_group.ToString()} {trayID} 获取筛选结果成功 ErrorCode {errorCode}";

                    if (result.Data.CellVos == null || result.Data.CellVos.Count == 0 || result.Data.CellVos.Count(x => x.Results == 1) == 400)
                    {
                        errorCode = "8215";
                        log = $"IMS-{errorCode} - Empty Tray or NG Tray.({trayInfo.TrayID})";
                    }
                    else
                    {
                        var count = result.Data.CellVos.Count(x => x.Results == 0 || x.Results == 2);
                        if (count == 400)
                        {
                            errorCode = "8306";
                        }

                        log = $"IMS-{errorCode} - All Cell Good.({trayInfo.TrayID})";

                        OnConnectStatusChanged?.Invoke(this, new ConnectStatusEventArgs
                        {
                            IsSuccess = true,
                            Connect = GetConnection(),
                            Message = $"{_group.ToString()} {trayID} 获取筛选结果成功,RouterCode {result.Data.RouterCode},StepCot {result.Data.StepCot} errorCode {errorCode},{trayID} 挑选电芯 {result.Data.CellVos.Count(x => x.Results == 1)}"
                        });


                    }


                }
                if (result.Data == null || result.Data.CellVos == null || result.Data.CellVos.Count == 0)
                {
                    GenerateData(trayInfo, errorCode, 50, 500);
                    return errorCode;
                }
                else
                {
                    GenerateData(trayInfo, errorCode, 50, 500);
                    var cells = result.Data.CellVos;
                    for (int l = 0; l < 400; l++)
                    {
                        PLC.CnvC.DbuffW[51 + l] = cells[l].Results;
                    }
                    Lf_WriteCharactorPLC(451, "", 3);
                    Lf_WriteCharactorPLC(453, result.Data.RouterCode.ToString(), 4);
                    Lf_WriteCharactorPLC(455, result.Data.StepCot.ToString(), 2);
                    log += string.Format("End Time [{0, -8}]:Type No({1, 4}), Proc No({2, 2}), Lot No({3, 3})", DateTime.Now.ToString("HH:mm:ss"), result.Data.RouterCode, result.Data.StepCot, "");
                    for (int m = 0; m < 400; m++)
                    {
                        if (m % 16 == 0)
                        {
                            log += "\n";
                        }
                        log += string.Format("[ {0, 2}, {1, 2} ] ", cells[m].Channel, cells[m].Results);
                    }

                }


                return errorCode;


            }
            catch (Exception ex2)
            {
                log = $"ReceiveMessage1107 Error => {ex2.Message}";
            }

        }

        return string.Empty;
    }

    private bool DbuffRLow2(int plcAddr, int imsAddr, ref string errorCode)
    {
        var PLC = _tcpHandle;
        if (PLC.CnvC.DbuffR[plcAddr] == 0)
        {
            if (PLC.CnvC.DbuffR[imsAddr] > 0)
            {
                PLC.CnvC.DbuffW[imsAddr] = 0;
                PLC.CnvC.DwRet = imsAddr;
                PLC.CnvC.DwRetAddr = PLC.DBUFF_OFFSET + imsAddr;
                PLC.CnvC.DwReq = 1;
                PLC.CnvC.DwAddr = PLC.DBUFF_OFFSET;
            }
        }
        else if (PLC.CnvC.DwReq <= 0 && PLC.CnvC.DwAddr <= 0 && PLC.CnvC.DwRetAddr <= 0)

        {
            ParserDefine trayInfo = new ParserDefine();
            string trayID = string.Empty;
            errorCode = string.Empty;
            int num = 0;
            log = string.Empty;

            try
            {

                trayID = Lf_ReadCharactorPLC(510, 4).Trim();


                trayInfo.TrayID = trayID;
                log += string.Format("[{0}] {1} ({2})", DateTime.Now.ToString("HH:mm:ss"), "Empty NG Tray", trayInfo.TrayID);


                trayInfo.StageNo = Lf_Copy(_group.Name, 7, 2).PadLeft(4, '0');

                // 再次判断是否是ng托盘
                var result = _connectDataService.CheckNGResult(new HkWriteInstruct  
                {
                    TrayID = trayID,
                    Num = _group.Num

                }).Result;
                if (result.IsSuccess)
                {

                    if (result.Msg != "999")
                    {
                        _group.Value = $"{_group.ToString()} {trayID} 检查NG托盘类型失败， Msg {result.Msg}";
                        errorCode = "8210";
                    }
                    else
                    {

                        _group.Value = $"{_group.ToString()} {trayID} 检查NG托盘类型成功， Msg {result.Msg}";
                    }
                }
                else
                {
                    errorCode = result.Msg;
                    _group.Value = $"{_group.ToString()} {trayID} 检查NG托盘类型失败， ErrorCode {result.Msg}";
                    OnConnectStatusChanged?.Invoke(this, new ConnectStatusEventArgs
                    {
                        IsSuccess = false,
                        Connect = GetConnection(),
                        Message = $"{_group.ToString()} {trayID} 检查NG托盘类型失败， ErrorCode {result.Msg}"
                    });
                }

                num = 1;


                GenerateData(trayInfo, errorCode, 520, 530);
                log += "\n";
                log += string.Format("End Time [{0, -8}]:Tray Type({1, 2})", DateTime.Now.ToString("HH:mm:ss"), trayInfo.TrayType);
                return true;
            }
            catch (Exception ex3)
            {
                log = $"ReceiveMessage1107 Error => {ex3.Message}";
            }

        }

        return false;
    }
    #endregion



    public void TrayInfomationSEL()
    {
        var PLC = _tcpHandle;

        log = string.Empty;
        string ecode = string.Empty;
        bool isHandle = false;

        // 读取请求地址，条码
        sgPLCAddr = 15;
        // 写入地址
        sgIMSAddr = 30;
        // IMS 清理写入信号
        if (PLC.CnvC.DwRetAddr != 0 || PLC.CnvC.DbuffR[sgPLCAddr] != 0 ? false : PLC.CnvC.DbuffW[sgIMSAddr] > 0)
        {
            PLC.CnvC.DbuffW[sgIMSAddr] = 0;
            PLC.CnvC.DwRet = sgIMSAddr;
            // offset=10000     30
            PLC.CnvC.DwRetAddr = PLC.DBUFF_OFFSET + sgIMSAddr;
            PLC.CnvC.DwReq = 1;
            // dwaddr=10000
            PLC.CnvC.DwAddr = PLC.DBUFF_OFFSET;
        }

        else if (PLC.CnvC.DbuffW[sgIMSAddr] <= 0)
        {
            // 交互，查询trayid
            isHandle = DbuffRLow(15, 30, ref ecode);
        }
        sgPLCAddr = 45;
        sgIMSAddr = 500;
        if (PLC.CnvC.DwRetAddr != 0 || PLC.CnvC.DbuffR[sgPLCAddr] != 0 ? false : PLC.CnvC.DbuffW[sgIMSAddr] > 0)
        {
            PLC.CnvC.DbuffW[sgIMSAddr] = 0;
            PLC.CnvC.DwRet = sgIMSAddr;
            PLC.CnvC.DwRetAddr = PLC.DBUFF_OFFSET + sgIMSAddr;
            PLC.CnvC.DwReq = 1;
            PLC.CnvC.DwAddr = PLC.DBUFF_OFFSET;
        }
        else if (PLC.CnvC.DbuffW[sgIMSAddr] <= 0)
        {
            ecode = DbuffRLow1(45, 500);
            if (ecode != "8306")
            {
                _group.Value = ecode;
            }
        }
        sgPLCAddr = 515;
        sgIMSAddr = 530;
        if (PLC.CnvC.DwRetAddr != 0 || PLC.CnvC.DbuffR[sgPLCAddr] != 0 ? false : PLC.CnvC.DbuffW[sgIMSAddr] > 0)
        {
            PLC.CnvC.DbuffW[sgIMSAddr] = 0;
            PLC.CnvC.DwRet = sgIMSAddr;
            PLC.CnvC.DwRetAddr = PLC.DBUFF_OFFSET + sgIMSAddr;
            PLC.CnvC.DwReq = 1;
            PLC.CnvC.DwAddr = PLC.DBUFF_OFFSET;
        }
        else if (PLC.CnvC.DbuffW[sgIMSAddr] <= 0)
        {
            isHandle = DbuffRLow2(515, 530, ref ecode);
        }


    }

    #endregion

    private void CommControl()
    {

        if (!this.GetConnection())
        {

            // 重连机制
            CommPhase00();
            this._tcpHandle.CnvC.CommPhs = 10;
        }
        else
        {
            if (this._tcpHandle.CnvC.CommPhs == 0)
            {
                this._tcpHandle.CnvC.CommPhs = 10;
            }
        }
        do
        {
            switch (this._tcpHandle.CnvC.CommPhs)
            {
                case 0:
                    // 重连机制
                    CommPhase00();
                    break;
                case 10:
                    // TxBuffB 赋值,发送  DwReq=0 return 20     end 11 
                    CommPhase10();
                    break;
                case 11:
                    // CommPhs赋值
                    CommPhase11();
                    break;
                case 20:
                    // CommPhs赋值
                    CommPhase20();
                    break;
                case 21:
                    // CommPhs赋值
                    CommPhase21();
                    break;
                case 30:
                    // TxBuffB 赋值
                    CommPhase30();
                    break;
                case 31:
                    // CommPhs 赋值
                    CommPhase31();
                    break;
                case 40:
                    //
                    CommPhase40();
                    break;
                case 41:
                    // DbuffR 赋值 ，来自采集的 RxBuffB
                    CommPhase41();
                    break;
                case 50:
                    // TxBuffB 赋值，心跳
                    CommPhase50();
                    break;
                case 51:
                    // CommPhs赋值
                    CommPhase51();
                    break;
                case 90:
                    CommPhase90();
                    CommPhase91();
                    CommPhase92();
                    CommPhase93();

                    this._tcpHandle.CnvCommOK = 1;
                    this._tcpHandle.CnvC.CommPhs = 10;
                    break;
            }
        }
        while (this._tcpHandle.CnvC.CommPhs != 0 && (int)this._tcpHandle.CnvC.CommPhs % 10 <= 0);






    }


    /// <summary>
    /// 构造发送数据
    /// </summary>
    /// <param name="trayInfo"></param>
    /// <param name="errorCode"></param>
    /// <param name="stIMSAddr"></param>
    /// <param name="edIMSAddr"></param>
    private void GenerateData(ParserDefine trayInfo, string errorCode, int stIMSAddr, int edIMSAddr)
    {
        var PLC = _tcpHandle;


        PLC.CnvC.DwWordS = stIMSAddr;
        PLC.CnvC.DwWordE = edIMSAddr;
        for (int j = PLC.CnvC.DwWordS; j < PLC.CnvC.DwWordE; j++)
        {
            PLC.CnvC.DbuffW[j] = 0;
        }



        if (errorCode == "")
        {
            PLC.CnvC.DbuffW[stIMSAddr] = 1;
        }
        else
        {
            PLC.CnvC.DbuffW[stIMSAddr] = Lf_StrToIntDef(errorCode, 9000);
        }

        PLC.CnvC.DbuffW[edIMSAddr] = 1;
        PLC.CnvC.DwRet = edIMSAddr;
        PLC.CnvC.DwRetAddr = PLC.DBUFF_OFFSET + sgIMSAddr;
        PLC.CnvC.DwReq = 1;
        PLC.CnvC.DwAddr = PLC.DBUFF_OFFSET;



    }

    #region TrayResult
    private bool DataSEL(int plcAddr, int imsAddr, ref string errorCode)
    {
        var PLC = _tcpHandle;
        if (PLC.CnvC.DbuffR[plcAddr] == 0)
        {
            if (PLC.CnvC.DbuffR[imsAddr] > 0)
            {
                PLC.CnvC.DbuffW[imsAddr] = 0;
                PLC.CnvC.DwRet = imsAddr;
                PLC.CnvC.DwRetAddr = PLC.DBUFF_OFFSET + imsAddr;
                PLC.CnvC.DwReq = 1;
                PLC.CnvC.DwAddr = PLC.DBUFF_OFFSET;
            }
        }
        else if (PLC.CnvC.DwReq <= 0 && PLC.CnvC.DwAddr <= 0 && PLC.CnvC.DwAddr <= 0)
        {
            ParserDefine trayInfo = new ParserDefine();


            try
            {
                int num2 = 0;
                log = string.Empty;
                errorCode = string.Empty;
                var trayID = Lf_ReadCharactorPLC(540, 4).Trim();


                trayInfo.TrayID = trayID;
                log += string.Format("[{0}] {1} ({2, 3})", DateTime.Now.ToString("HH:mm:ss"), "NG Cell Transfer", trayInfo.TrayID.ToString());


                trayInfo.StageNo = Lf_Copy(_group.Name, 7, 2).PadLeft(4, '0');
                num2 = 1;
                if (num2 == 0)
                {
                    errorCode = "8201";
                    log = $"IMS-{errorCode} - Unregistered tray.({trayInfo.TrayID})";
                }
                else
                {


                    var num4 = PLC.CnvC.DbuffR[544];
                    if (num4 < 0 || num4 > 400)
                    {
                        errorCode = "8215";
                        log = string.Format("IMS-{0} - Cell Source Channel No Abnormal.({1}, {2})", errorCode, num4, "#1 Gripper");
                    }


                }



                GenerateData(trayInfo, errorCode, 580, 590);

                int och = PLC.CnvC.DbuffR[544];
                string tray = this.Lf_ReadCharactorPLC(545, 4).Trim();

                int nch = PLC.CnvC.DbuffR[549];
                string ngcode = this.Lf_ReadCharactorPLC(550, 1).Trim();


                int och1 = PLC.CnvC.DbuffR[551];
                string tray1 = this.Lf_ReadCharactorPLC(552, 4).Trim();
                int nch1 = PLC.CnvC.DbuffR[556];
                string ngcode1 = Lf_ReadCharactorPLC(557, 1).Trim();

                OnConnectStatusChanged?.Invoke(this, new ConnectStatusEventArgs
                {
                    Connect = true,
                    IsSuccess = true,
                    Message = $"trayid {trayID}  och {och} tray {tray} nch {nch} ngcode {ngcode} ---- och1 {och1} tray1 {tray1} nch1 {nch1} ngcode1 {ngcode1}"
                });




                return true;

            }
            catch (Exception ex)
            {
                log = $"ReceiveMessage1107 Error => {ex.Message}";
            }


        }

        return false;
    }


    private string DataSEL1(int plcAddr, int imsAddr)
    {
        string errorCode = string.Empty;
        var PLC = _tcpHandle;

        if (PLC.CnvC.DbuffR[plcAddr] == 0)
        {
            if (PLC.CnvC.DbuffR[imsAddr] > 0)
            {
                PLC.CnvC.DbuffW[imsAddr] = 0;
                PLC.CnvC.DwRet = imsAddr;
                PLC.CnvC.DwRetAddr = PLC.DBUFF_OFFSET + imsAddr;
                PLC.CnvC.DwReq = 1;
                PLC.CnvC.DwAddr = PLC.DBUFF_OFFSET;
            }
        }
        else if (PLC.CnvC.DwReq <= 0 && PLC.CnvC.DwAddr <= 0 && PLC.CnvC.DwAddr <= 0)
        {

            ParserDefine trayInfo = new ParserDefine();

            try
            {
                int num2 = 0;
                errorCode = string.Empty;
                log = string.Empty;
                var trayID = Lf_ReadCharactorPLC(600, 4).Trim();


                // 提交最终的结果
                var result = _connectDataService.CommitSelResult(new HkWriteInstruct
                {
                    TrayID = trayID,
                    Num = _group.Num
                }).Result;

                if (!result.IsSuccess)
                {

                    OnConnectStatusChanged?.Invoke(this, new ConnectStatusEventArgs
                    {
                        Connect = GetConnection(),
                        IsSuccess = false,
                        Message = $"{_group.ToString()} {trayID} 筛选结果提交失败,{result.Msg}"
                    });
                    _group.Value = $"{_group.ToString()} {trayID} 筛选结果提交失败";


                    errorCode = result.Msg;
                }
                else
                {
                    OnConnectStatusChanged?.Invoke(this, new ConnectStatusEventArgs
                    {
                        Connect = GetConnection(),
                        IsSuccess = true,
                        Message = $"{_group.ToString()} {trayID} 筛选结果提交成功"
                    });
                    _group.Value = $"{_group.ToString()} {trayID} 筛选结果提交成功";
                    _group.TrayNo = String.Empty;
                }


                trayInfo.TrayID = trayID;
                log += string.Format("[{0}] {1} ({2})", DateTime.Now.ToString("HH:mm:ss"), "Process Finish Tray", trayInfo.TrayID);


                trayInfo.StageNo = Lf_Copy(_group.Name, 7, 2).PadLeft(4, '0');


                num2 = 1;

                if (num2 == 0)
                {
                    errorCode = "8201";
                    log = $"IMS-{errorCode} - Unregistered tray.({trayInfo.TrayID})";
                }
                else
                {
                    //DbManager.Lf_CheckTrayInRack(_group.LineNo, TrayInfo3.TrayID, 0, ref text5);


                    //else if (TrayInfo3.TypeNo == "" || TrayInfo3.ProcNo == "")
                    //{
                    //    text4 = "8228";
                    //    text5 = $"IMS-{text4} - Process number not set.({TrayInfo3.TrayID})";
                    //}
                    //else

                    // await DbManager.Lf_ProcessTypeCheck(_group.LineNo, TrayInfo3, 0);



                    trayInfo.ProcType = "SEL";

                    // num2 = DbManager.Lf_CheckInTrayCellStatus(_group.LineNo, TrayInfo3.TrayID, 1, 1, ref text5);
                    num2 = 0;
                    if (num2 == 1)
                    {
                        errorCode = "8212";
                        log = $"IMS-{errorCode} - There are unprocessed cells.({trayInfo.TrayID})";
                    }

                    //LogManager.ImsPlcLog("TX", log);

                }

                GenerateData(trayInfo, errorCode, 610, 620);
                PLC.CnvC.DbuffW[486] = 0;
                log += "\n";
                log += string.Format("End Time [{0, -8}]:Tray Type({1, 2}, Type No({2, 4}, Proc No({3, 2})", DateTime.Now.ToString("HH:mm:ss"), trayInfo.TrayType, trayInfo.TypeNo, trayInfo.ProcNo);


                return string.Empty;

            }
            catch (Exception ex2)
            {
                log = $"ReceiveMessage1107 Error => {ex2.Message}";
            }

        }

        return String.Empty;
    }


    private string DataSEL2(int plcAddr, int imsAddr)
    {
        string errorCode = string.Empty;
        var PLC = _tcpHandle;
        if (PLC.CnvC.DbuffR[plcAddr] == 0)
        {
            if (PLC.CnvC.DbuffR[imsAddr] > 0)
            {
                PLC.CnvC.DbuffW[imsAddr] = 0;
                PLC.CnvC.DwRet = imsAddr;
                PLC.CnvC.DwRetAddr = PLC.DBUFF_OFFSET + imsAddr;
                PLC.CnvC.DwReq = 1;
                PLC.CnvC.DwAddr = PLC.DBUFF_OFFSET;
            }
        }
        else if (PLC.CnvC.DwReq <= 0 && PLC.CnvC.DwAddr <= 0 && PLC.CnvC.DwAddr <= 0)
        {

            ParserDefine trayInfo = new ParserDefine();

            try
            {
                int num2 = 0;
                errorCode = string.Empty;
                log = string.Empty;
                var trayID = Lf_ReadCharactorPLC(630, 4).Trim();
                if (trayID.IsNullOrEmpty())
                {
                    return string.Empty;
                }
                else
                {



                    trayInfo.TrayID = trayID;
                    log += string.Format("[{0}] {1} ({2})", DateTime.Now.ToString("HH:mm:ss"), "NG Tray Output", trayInfo.TrayID);

                    //LogManager.ImsPlcLog("RX", log);
                    trayInfo.StageNo = Lf_Copy(_group.Name, 7, 2).PadLeft(4, '0');
                    // num2 = DbManager.Lf_TrayInfoAndExists(_group.LineNo, TrayInfo4.TrayID, 1, ref TrayInfo4, ref text5);
                    num2 = 1;
                    if (num2 == 0)
                    {
                        errorCode = "8201";
                        log = $"IMS-{errorCode} - Unregistered tray.({trayInfo.TrayID})";
                    }
                    else
                    {

                        num2 = 0;
                        if (num2 == 1)
                        {
                            errorCode = "8212";
                            log = $"IMS-{errorCode} - Cell Normal cell exists.({trayInfo.TrayID})";
                        }
                        else if (trayInfo.TypeNo != "" || trayInfo.ProcNo != "")
                        {
                            errorCode = "8403";
                            log = $"IMS-{errorCode} - It is not an NG tray.({trayInfo.TrayID})";
                        }


                    }
                }
                GenerateData(trayInfo, errorCode, 640, 650);
                log += "\n";
                log += string.Format("End Time [{0, -8}]:Tray Type({1, 2})", DateTime.Now.ToString("HH:mm:ss"), trayInfo.TrayType);



                return errorCode;



            }
            catch (Exception ex3)
            {
                log = $"ReceiveMessage1107 Error => {ex3.Message}";
            }

        }


        return string.Empty;
    }
    #endregion
    public void TrayResultdataSEL()
    {
        var PLC = _tcpHandle;

        log = "";

        bool isHandle = false;

        string ecode = string.Empty;

        sgPLCAddr = 575;
        sgIMSAddr = 590;
        if (PLC.CnvC.DwRetAddr != 0 || PLC.CnvC.DbuffR[sgPLCAddr] != 0 ? false : PLC.CnvC.DbuffW[sgIMSAddr] > 0)
        {
            PLC.CnvC.DbuffW[sgIMSAddr] = 0;
            PLC.CnvC.DwRet = sgIMSAddr;
            PLC.CnvC.DwRetAddr = PLC.DBUFF_OFFSET + sgIMSAddr;
            PLC.CnvC.DwReq = 1;
            PLC.CnvC.DwAddr = PLC.DBUFF_OFFSET;
        }
        else if (PLC.CnvC.DbuffW[sgIMSAddr] <= 0)
        {
            isHandle = DataSEL(575, 590, ref ecode);

        }


        sgPLCAddr = 605;
        sgIMSAddr = 620;
        if (PLC.CnvC.DwRetAddr != 0 || PLC.CnvC.DbuffR[sgPLCAddr] != 0 ? false : PLC.CnvC.DbuffW[sgIMSAddr] > 0)
        {
            PLC.CnvC.DbuffW[sgIMSAddr] = 0;
            PLC.CnvC.DwRet = sgIMSAddr;
            PLC.CnvC.DwRetAddr = PLC.DBUFF_OFFSET + sgIMSAddr;
            PLC.CnvC.DwReq = 1;
            PLC.CnvC.DwAddr = PLC.DBUFF_OFFSET;
        }
        else if (PLC.CnvC.DbuffW[sgIMSAddr] <= 0)
        {
            ecode = DataSEL1(605, 620);

        }
        sgPLCAddr = 635;
        sgIMSAddr = 650;
        if (PLC.CnvC.DwRetAddr != 0 || PLC.CnvC.DbuffR[sgPLCAddr] != 0 ? false : PLC.CnvC.DbuffW[sgIMSAddr] > 0)
        {
            PLC.CnvC.DbuffW[sgIMSAddr] = 0;
            PLC.CnvC.DwRet = sgIMSAddr;
            PLC.CnvC.DwRetAddr = PLC.DBUFF_OFFSET + sgIMSAddr;
            PLC.CnvC.DwReq = 1;
            PLC.CnvC.DwAddr = PLC.DBUFF_OFFSET;
        }
        else if (PLC.CnvC.DbuffW[sgIMSAddr] <= 0)
        {
            ecode = DataSEL2(635, 650);
        }



    }


    public void EquipmentAlarm()
    {
        var PLC = _tcpHandle;
        string text = "";
        int num = PLC.CnvC.DbuffR[1] & 8;
        int num2 = PLC.CnvC.DbuffR[2];
        if (num2 > 0)
        {
            text = $"{num2:d5}";
        }
        if ((text == "" && num > 0) || (buffSave == DateTime.MinValue && num == 0) || (buffSave > DateTime.MinValue && num > 0 && text == _group.Value))
        {
            return;
        }
        // equipno
        _parser.MachNo = Lf_Copy(_group.Name, 7, 2).PadLeft(4, '0');
        _parser.MachType = Lf_Copy(_group.Name, 2, 3);
        _parser.AlarmMsg = "";
       
        if (num == 0 && buffSave > DateTime.MinValue)
        {
            _parser.TimeS = buffSave.ToString("yyyyMMddHHmmss");
            _parser.TimeE = DateTime.Now.ToString("yyyyMMddHHmmss");

            buffSave = DateTime.MinValue;

        }
        else if (num > 0 && text != "" && text != _group.Value)
        {

            if (buffSave == DateTime.MinValue)
            {
                _parser.StageNo = HbcExtension.EquipNameToStageNo(_group.Name);

            }
            buffSave = DateTime.Now;
            _parser.TimeS = buffSave.ToString("yyyyMMddHHmmss");
            _parser.TimeE = "";

        }
    }

    public void EquipmentState()
    {
        var PLC = _tcpHandle;
        if (PLC.CnvC.DbuffR[1] == 0)
        {
            _group.EquipState = 0;
        }
        if ((PLC.CnvC.DbuffR[1] & 1) > 0)
        {
            _group.EquipState = 1;
        }
        if ((PLC.CnvC.DbuffR[1] & 2) > 0)
        {
            _group.EquipState = 2;
        }
        if ((PLC.CnvC.DbuffR[1] & 4) > 0)
        {
            _group.EquipState = 3;
        }
        if ((PLC.CnvC.DbuffR[1] & 8) > 0)
        {
            _group.EquipState = 4;
        }

    }

    public async Task<bool> OperationStop()
    {
        try
        {
            _cancellationTokenSource?.Cancel();
            _tcpHandle?.DisconnectServer();

            _timer.Stop();
            _status = false;
        }
        catch (Exception ex)
        {
            OnConnectStatusChanged.Invoke(this, new ConnectStatusEventArgs
            {
                Connect = false,
                IsSuccess = true,
                Message = $"{_group.ToString()} Stop,{ex.Message}"
            });
        }

        return true;
    }

    public Task<bool> WriteRequest(OperationWriteCommand writeInfo)
    {
        throw new NotImplementedException();
    }

    public void Dispose()
    {
        OperationStop();
    }
}
